/*
 * AnchorLayout.h
 *
 *  Created on: May 14, 2017
 *      Author: wangguojian
 */

#ifndef ANCHORLAYOUT_H_
#define ANCHORLAYOUT_H_

namespace CrossApp {
class CAView;
}

class AnchorBase
{
public:
	enum class AlignmentH : unsigned int {
			Left = 0x0,
			Right,
			Invalid
	};
	enum class AlignmentV : unsigned int {
		Top = 0x0,
		Bottom,
		Invalid
	};
	AnchorBase();

	AnchorBase(CrossApp::CAView *alignmentView = nullptr,
			float margin = 0,
			AnchorBase::AlignmentH alignment = AnchorBase::AlignmentH::Invalid);

	AnchorBase(CrossApp::CAView *alignmentView = nullptr,
			float margin = 0,
			AnchorBase::AlignmentV alignment = AnchorBase::AlignmentV::Invalid);

	virtual ~AnchorBase();

	CrossApp::CAView *getAlignmentView() const;
	AnchorBase::AlignmentH getAlignmentH() const;
	AnchorBase::AlignmentV getAlignmentV() const;
	float getMargin() const;
protected:
	CrossApp::CAView *mAlignmentView;
	AnchorBase::AlignmentH mAlignmentH;
	AnchorBase::AlignmentV mAlignmentV;
	float mMargin;
};

class AnchorLeft : public AnchorBase
{
public:
	AnchorLeft();
	AnchorLeft(CrossApp::CAView *alignmentView,
			float margin = 0,
			AnchorBase::AlignmentH alignment = AnchorBase::AlignmentH::Right);
	~AnchorLeft();
	AnchorLeft &operator = (const AnchorLeft &other);
};

class AnchorRight : public AnchorBase
{
public:
	AnchorRight();
	AnchorRight(CrossApp::CAView *alignmentView,
			float margin = 0,
			AnchorBase::AlignmentH alignment = AnchorBase::AlignmentH::Left);
	~AnchorRight();
	AnchorRight &operator = (const AnchorRight &other);
};

class AnchorTop : public AnchorBase
{
public:
	AnchorTop();
	AnchorTop(CrossApp::CAView *alignmentView,
			float margin = 0,
			AnchorBase::AlignmentV alignment = AnchorBase::AlignmentV::Bottom);
	~AnchorTop();
	AnchorTop &operator = (const AnchorTop &other);
};

class AnchorBottom : public AnchorBase
{
public:
	AnchorBottom();
	AnchorBottom(CrossApp::CAView *alignmentView,
			float margin = 0,
			AnchorBase::AlignmentV alignment = AnchorBase::AlignmentV::Top);
	~AnchorBottom();
	AnchorBottom &operator = (const AnchorBottom &other);
};

class AnchorHorizontal
{
public:
	AnchorHorizontal();
	AnchorHorizontal(const AnchorHorizontal &other);
	AnchorHorizontal(const AnchorLeft &left, const AnchorRight &right);
	AnchorHorizontal(const AnchorLeft &left, float width);
	AnchorHorizontal(const AnchorRight &right, float width);
	~AnchorHorizontal();
	AnchorLeft getLeft() const;
	AnchorRight getRight() const;
	float getWidth() const;
	AnchorHorizontal &operator = (const AnchorHorizontal &other);
private:
	AnchorLeft mLeft;
	AnchorRight mRight;
	float mWidth;

};

class AnchorVertical
{
public:
	AnchorVertical();
	AnchorVertical(const AnchorVertical &other);
	AnchorVertical(const AnchorTop &top, const AnchorBottom &bottom);
	AnchorVertical(const AnchorTop &top, float height);
	AnchorVertical(const AnchorBottom &bottom, float height);
	~AnchorVertical();
	AnchorTop getTop() const;
	AnchorBottom getBottom() const;
	float getHeight() const;
	AnchorVertical &operator = (const AnchorVertical &other);
private:
	AnchorTop mTop;
	AnchorBottom mBottom;
	float mHeight;
};

class AnchorLayout
{
public:
	AnchorHorizontal horizontal;
	AnchorVertical vertical;

public:
	AnchorLayout();
	AnchorLayout(const AnchorLayout &other);
	AnchorLayout(const AnchorHorizontal &horizontal, const AnchorVertical &vertical);
	AnchorLayout(const AnchorLeft &left, const AnchorRight &right,
			const AnchorTop &top, const AnchorBottom &bottom);
	virtual ~AnchorLayout();
	AnchorLayout &operator = (const AnchorLayout &other);
};

inline AnchorHorizontal anchorH_LL_W(CrossApp::CAView *view, float margin, float width) {
	return AnchorHorizontal(AnchorLeft(view, margin, AnchorBase::AlignmentH::Left), width);
}
inline AnchorHorizontal anchorH_LR_W(CrossApp::CAView *view, float margin, float width) {
	return AnchorHorizontal(AnchorLeft(view, margin, AnchorBase::AlignmentH::Right), width);
}
inline AnchorHorizontal anchorH_RL_W(CrossApp::CAView *view, float margin, float width) {
	return AnchorHorizontal(AnchorRight(view, margin, AnchorBase::AlignmentH::Left), width);
}
inline AnchorHorizontal anchorH_RR_W(CrossApp::CAView *view, float margin, float width) {
	return AnchorHorizontal(AnchorRight(view, margin, AnchorBase::AlignmentH::Right), width);
}
inline AnchorHorizontal anchorH_LL_RL(CrossApp::CAView *lView, float lMargin,
									  CrossApp::CAView *rView, float rMargin) {
	return AnchorHorizontal(AnchorLeft(lView, lMargin, AnchorBase::AlignmentH::Left),
							AnchorRight(rView, rMargin, AnchorBase::AlignmentH::Left));
}
inline AnchorHorizontal anchorH_LL_RR(CrossApp::CAView *lView, float lMargin,
		  	  	  	  	  	  	  	  CrossApp::CAView *rView, float rMargin) {
	return AnchorHorizontal(AnchorLeft(lView, lMargin, AnchorBase::AlignmentH::Left),
							AnchorRight(rView, rMargin, AnchorBase::AlignmentH::Right));
}
inline AnchorHorizontal anchorH_LR_RL(CrossApp::CAView *lView, float lMargin,
		  	  	  	  	  	  	  	  CrossApp::CAView *rView, float rMargin) {
	return AnchorHorizontal(AnchorLeft(lView, lMargin, AnchorBase::AlignmentH::Right),
							AnchorRight(rView, rMargin, AnchorBase::AlignmentH::Left));
}
inline AnchorHorizontal anchorH_LR_RR(CrossApp::CAView *lView, float lMargin,
		  	  	  	  	  	  	  	  CrossApp::CAView *rView, float rMargin) {
	return AnchorHorizontal(AnchorLeft(lView, lMargin, AnchorBase::AlignmentH::Right),
							AnchorRight(rView, rMargin, AnchorBase::AlignmentH::Right));
}

inline AnchorVertical anchorV_TT_H(CrossApp::CAView *view, float margin, float height) {
	return AnchorVertical(AnchorTop(view, margin, AnchorBase::AlignmentV::Top), height);
}
inline AnchorVertical anchorV_TB_H(CrossApp::CAView *view, float margin, float height) {
	return AnchorVertical(AnchorTop(view, margin, AnchorBase::AlignmentV::Bottom), height);
}
inline AnchorVertical anchorV_BT_H(CrossApp::CAView *view, float margin, float height) {
	return AnchorVertical(AnchorBottom(view, margin, AnchorBase::AlignmentV::Top), height);
}
inline AnchorVertical anchorV_BB_H(CrossApp::CAView *view, float margin, float height) {
	return AnchorVertical(AnchorBottom(view, margin, AnchorBase::AlignmentV::Bottom), height);
}
inline AnchorVertical anchorV_TT_BT(CrossApp::CAView *tView, float tMargin,
									CrossApp::CAView *bView, float bMargin) {
	return AnchorVertical(AnchorTop(tView, tMargin, AnchorBase::AlignmentV::Top),
						  AnchorBottom(bView, bMargin, AnchorBase::AlignmentV::Top));
}
inline AnchorVertical anchorV_TT_BB(CrossApp::CAView *tView, float tMargin,
									CrossApp::CAView *bView, float bMargin) {
	return AnchorVertical(AnchorTop(tView, tMargin, AnchorBase::AlignmentV::Top),
						  AnchorBottom(bView, bMargin, AnchorBase::AlignmentV::Bottom));
}
inline AnchorVertical anchorV_TB_BT(CrossApp::CAView *tView, float tMargin,
									CrossApp::CAView *bView, float bMargin) {
	return AnchorVertical(AnchorTop(tView, tMargin, AnchorBase::AlignmentV::Bottom),
						  AnchorBottom(bView, bMargin, AnchorBase::AlignmentV::Top));
}
inline AnchorVertical anchorV_TB_BB(CrossApp::CAView *tView, float tMargin,
									CrossApp::CAView *bView, float bMargin) {
	return AnchorVertical(AnchorTop(tView, tMargin, AnchorBase::AlignmentV::Bottom),
						  AnchorBottom(bView, bMargin, AnchorBase::AlignmentV::Bottom));
}


#endif /* ANCHORLAYOUT_H_ */
